import com.google.gson.Gson;
import de.onvif.soap.OnvifDevice;
import de.onvif.soap.devices.InitialDevices;
import de.onvif.soap.devices.PtzDevices;
import org.onvif.ver10.schema.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * Author      jxx
 * Motto       让世界看到我
 * On          2023/10/31 11:45
 * Version     v1.0
 * Note        TODO
 */
public class Onvif {

    static class XJ {
        public String ip;
        public String username;
        public String password;
    }

    static List<XJ> xjs = new ArrayList<>();

    static {
        XJ xj1 = new XJ();
        xj1.ip = "192.168.101.105";
        xj1.username = "admin";
        xj1.password = "admin12345";

        XJ xj2 = new XJ();
        xj2.ip = "192.168.101.64";
        xj2.username = "admin";
        xj2.password = "hf123456";

        XJ xj3 = new XJ();
        xj3.ip = "192.168.101.65";
        xj3.username = "admin";
        xj3.password = "hf123456";

        //xjs.add(xj1);
        //xjs.add(xj2);
        xjs.add(xj3);
    }

    static OnvifDevice device;
    static List<Profile> profiles;
    static String profileToken;
    static PtzDevices ptz;

    static {
        try {
            //device = new OnvifDevice("192.168.101.105", "admin", "admin12345");
            //profiles = device.getDevices().getProfiles();
            //profileToken = profiles.get(0).getToken();
            //ptz = device.getPtz();
        } catch (Exception e) {
            System.out.println("初始化onvif对象错误");
            e.printStackTrace();
            System.exit(0);
        }
    }

    public static void main(String[] args) {
        try {
            test1();
            //test2();
            //test3();
            //test4();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("出现异常:" + e.getClass().getName() + "-->" + e.getMessage());
        }
    }

    private static void test4() throws UnsupportedEncodingException {
        String url = "http://192.168.101.102:8080/api/测试.pdf";
        System.out.println(url);
        String encode = URLEncoder.encode(url, String.valueOf(Charset.defaultCharset()));
        System.out.println(encode);
        String decode = URLDecoder.decode(encode, String.valueOf(Charset.defaultCharset()));
        System.out.println(decode);
    }

    private static void test3() {
        for (XJ xj : xjs) {
            try {
                System.out.println(xj.ip + ":" + xj.username + ":" + xj.password);
                OnvifDevice device = new OnvifDevice(xj.ip, xj.username, xj.password);
                // 获取设备信息
                //System.err.println(device.getDeviceUri());
                //System.out.println(device.getName());
                //System.err.println(device.encryptPassword());
                //System.err.println(device.getEncryptedPassword());
                //System.err.println(device.getHostname());

                InitialDevices devices = device.getDevices();
                System.err.println(devices);
                System.err.println(devices.getProfiles());

                //List<Profile> profiles = device.getDevices().getProfiles();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static void test2() {
        try {
            System.out.println("稍等将转动云台");
            Thread.sleep(200);
            long time1 = System.currentTimeMillis();
            ptz.continuousMove(profileToken, 0.2f, 0f, 0f);
            long time2 = System.currentTimeMillis();
            System.out.println("执行云台控制命令耗时:" + (time2 - time1));
            System.out.println("稍等将停止转动云台");
            Thread.sleep(2000);
            long time3 = System.currentTimeMillis();
            System.out.println("执行云台控制到结束耗时:" + (time3 - time2));
            ptz.stopMove(profileToken);
            long time4 = System.currentTimeMillis();
            System.out.println("执行云台控制停止命令耗时:" + (time4 - time3));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void test1() {
        for (XJ xj : xjs) {
            try {
                long time1 = System.currentTimeMillis();
                OnvifDevice device = new OnvifDevice(xj.ip, xj.username, xj.password);
                long time2 = System.currentTimeMillis();
                System.out.println("创建onvif设备对象耗时:" + (time2 - time1));
                // 获取设备信息
                System.out.println(new Gson().toJson(xj));
//                GetDeviceInformationResponse deviceInformation = device.getDevices().getDeviceInformation();
//
//                System.out.println("设备制造商: " + deviceInformation.getManufacturer());
//                System.out.println("设备模型: " + deviceInformation.getModel());
//                System.out.println("设备固件版本: " + deviceInformation.getFirmwareVersion());
//                System.out.println("设备序列号: " + deviceInformation.getSerialNumber());
//                System.out.println("设备硬件id: " + deviceInformation.getHardwareId());

                List<Profile> profiles = device.getDevices().getProfiles();
                long time3 = System.currentTimeMillis();
                System.out.println("获取profile对象耗时:" + (time3 - time2));
                for (Profile profile : profiles) {
                    String profileToken = profile.getToken();
                    System.out.println("profileToken=====" + profileToken);
                    StreamSetup streamSetup = new StreamSetup();
                    Transport transport = new Transport();
                    transport.setProtocol(TransportProtocol.UDP);
                    streamSetup.setStream(StreamType.RTP_UNICAST);
                    streamSetup.setTransport(transport);
                    // 流地址
                    String getStreamUri = device.getMedia().getStreamUri(profileToken, streamSetup);
                    System.out.println("流地址:" + getStreamUri);

                    //视频参数
                    //String videoSourceToken = profile.getVideoSourceConfiguration().getSourceToken();
                    //System.out.println("videoSourceToken=====" + videoSourceToken);
                    //ImagingSettings20 imagingSettings20 = device.getImaging().getImagingSettings(videoSourceToken);
                    //System.out.println("imagingSettings20:"+imagingSettings20.);
                }

                String profileToken = profiles.get(0).getToken();
                long time4 = System.currentTimeMillis();
                System.out.println("获取profile token对象耗时:" + (time4 - time3));
                // 设置视频参数上下转动
                //PtzDevices ptzDevices = device.getPtz();
                //PTZStatus status = ptzDevices.getStatus(profileToken);
                // 获取当前焦距
                //PTZVector position = status.getPosition();
                //System.out.println("position:"+new Gson().toJson(position));

                PtzDevices ptz = device.getPtz();
                if (!ptz.isContinuosMoveSupported(profileToken)) {
                    System.out.println("设备不支持onvifptz");
                    return;
                } else {
                    System.out.println("设备支持onvif");
                }
                long time5 = System.currentTimeMillis();
                System.out.println("判断是否支持onvif耗时:" + (time5 - time4));
                ptz.continuousMove(profileToken, -0.5f, 0f, 0f);
                long time6 = System.currentTimeMillis();
                System.out.println("执行云台控制命令耗时:" + (time6 - time5));
                Thread.sleep(2000);
                long time7 = System.currentTimeMillis();
                System.out.println("执行云台控制到结束耗时:" + (time7 - time6));
                ptz.stopMove(profileToken);
                long time8 = System.currentTimeMillis();
                System.out.println("执行云台控制停止命令耗时:" + (time8 - time7));

            } catch (Exception e) {
                //e.printStackTrace();
                System.out.println("出现异常:" + e.getClass().getName() + "-->" + e.getMessage());
            }
        }
    }
}
